//************************************************************************
/// <copyrigth>2024-2025 Corporation.All Rights Reserved</copyrigth>
/// <author>tangyingzhong</author>
/// <contact>tangyz114987@outlook.com</contact>
/// <version>v1.0.0</version>
/// <describe>
/// Cross-Platform notifier which do not need to knwo who will handle the notification
///</describe>
/// <date>2024/5/6</date>
///***********************************************************************
#ifndef NOTIFIER_H
#define NOTIFIER_H

#include <atomic>
#include <mutex>
#include <vector>
#include <thread>
#include <queue>
#include "INotifier.h"
#include "ModuleLoader/ModuleConfig.h"

namespace SystemTool
{
    class CLASS_ITEM Notifier : public INotifier
    {
    public:
        // Construct the obj
        Notifier();

        // Destruct the obj
        virtual ~Notifier();

    private:
        // Copy construct
        Notifier(const Notifier& other) = delete;

        // Assignment
        Notifier& operator=(const Notifier& other) = delete;

    public:
        // Add handler
        virtual void Add(IHandler *pHandler);

        // Remove handler
        virtual void Remove(IHandler *pHandler);

        // Clear the handler
        virtual void Clear();

        // Send the notification
        virtual void Send(NArgs &Args);

    private:
        // Run task
        void Run();

        // Start the thread
        void StartThread();

        // Stop the thread
        void StopThread();

        // Add the task
        void PushTask(NArgs& arg);

        // Get the task
        NArgs PopTask();

        // Clear the task
        void ClearTask();

        // Handle task
        void HandleTask(NArgs& Args);

    private:
        // Lock for the container
        std::mutex* m_pLock = nullptr;

        // Target table
        std::vector<IHandler*>* m_pHandlerContainer = nullptr;

        // Exit the thread
        std::atomic<bool> *m_pbIsExit = nullptr;

        // Thread
        std::thread* m_pThread = nullptr;

        // Task lock
        std::mutex* m_pTaskLock = nullptr;

        // Task container
        std::queue<NArgs> *m_pvTaskContainer = nullptr;
    };
}

#endif // NOTIFIER_H
